<?php

namespace App\Models;

use App\Http\Controllers\Controller;
use App\Http\Controllers\ScoreRuleController;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 馆藏书籍  (检索后，访问后，才会显示在此表)
 * Class LibBook
 * @package app\Controller\model
 */
class LibBook extends BaseModel
{

    use HasFactory;

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'change_time';

    protected $table = "lib_book";


    public function setImgAttr($isbn)
    {
        $isbn = str_replace('-', '', $isbn); //馆藏书有 - 线
        $img = LibBookRecom::where('isbn', $isbn)->value('img');
        if (!empty($img)) return $img;

        //获取书籍封面
        $controllerObj = new Controller();
        $img = $controllerObj->getImgByIsbn($isbn);
        if (!empty($img)) return $img;

        return 'default/default_lib_book.png';
    }

    /**
     * 根据图书馆id 和 书目库 获取在本地的书籍id
     */
    public function getLibBookInfoId($book_info, $bar_code_info)
    {
        // $book_id = $this->where('metaid', $book_info['metaid'])->where('metatable', $book_info['metatable'])->value('id');
        $book_id = $book_info['metaid']; //测试版本不查询
        if (empty($book_id)) {
            try {
                $obj = new self();
                $obj->metaid = $book_info['metaid'];
                $obj->metatable = $book_info['metatable'];
                $obj->book_name = $book_info['book_name'];
                $obj->author = $book_info['author'];
                $obj->press = $book_info['press'];
                $obj->pre_time = $book_info['pre_time'];
                $obj->isbn = str_replace('-', '', $book_info['isbn']);
                $obj->old_isbn = $book_info['isbn']; //保存原本的isbn号
                $obj->price = $book_info['price'];
                $obj->img = $book_info['img'] ? $book_info['img'] : '';
                $obj->book_num = $book_info['book_num'];
                // $obj->type_big_id = Controller::getTypeBigId($book_info['book_num']);
                $obj->type_id = Controller::getTypeBigId($book_info['book_num']);

                $obj->save();
                $book_id = $obj->id;
            } catch (\Exception $e) {
                Log::error($e->getMessage());
                return null; //保存失败
            }
        }
        //还需要添加书籍对应的条形码信息
        $obj = new LibBookBarcode();
        $obj->libBookBarcodeAdd($book_id, $bar_code_info);

        return $book_id;
    }

    /**
     * 判断用户借阅管理员权限
     * @param  $is_admin 是否是 后台管理员验证
     * @param  $is_order_view 是否是 订单页面验证
     */
    public function checkNewBookBorrowAuth($account_info, $book_info, $is_admin = false, $is_order_view = false)
    {
        //判断是否在借阅流程中
        $this->checkNowIsBookHomePurchaseProcess($account_info['account_id'], $book_info, $is_admin, $is_order_view);

        $this->validateBorrowLibSystem($account_info, $book_info, $is_admin, $is_order_view);
        //判断此书是否在采购流程中
        $this->checkBookHomePurchaseIng($book_info, $is_admin, $is_order_view);
    }


    /**
     * 判断当前借阅的馆藏书是否在自己的采购流程中
     */
    public function checkNowIsBookHomePurchaseProcess($account_id, $book_info, $is_admin, $is_order_view)
    {
        //如果是后台就不验证此参数
        if ($is_admin) {
            return true;
        }
        $BookHomeOrderModelObj = new BookHomeOrder();
        foreach ($book_info as $key => $val) {
            $result = $BookHomeOrderModelObj->from($BookHomeOrderModelObj->getTable() . ' as o')
                ->select('o.is_pay')
                ->join('book_home_order_book as b', 'b.order_id', '=', 'o.id')
                ->join('lib_book_barcode as c', 'c.id', '=', 'b.barcode_id')
                ->where('c.barcode', $val['barcode'])
                ->where('o.account_id', $account_id)
                ->where(function ($query) use ($is_order_view) {
                    if ($is_order_view) {
                        $query
                            ->Orwhere('o.is_pay', 2)
                            ->Orwhere('o.is_pay', 6);
                    } else {
                        $query->Orwhere('o.is_pay', 1)
                            ->Orwhere('o.is_pay', 2)
                            ->Orwhere('o.is_pay', 6);
                        //->Orwhere('o.is_pay', 8);//已发货就是已经借阅了，交由opac系统判断
                    }
                })->first();

            if ($result) {
                $msg = $result['is_pay'] == 1 ? '支付' : '查看';
                throw new \Exception('条形码:' . $val['barcode'] . '，此书已经在借阅流程中，请到个人中心-物流订单' . $msg);
            }
        }
    }

    /**
     * 判断读者在图书馆借阅权限（馆藏书判断）
     * @param $book_info 书籍信息
     * @param $account_info 读者证信息
     * @param $is_admin 是否是后台验证
     * @param $is_order_view 是否是读者订单界面重新获取
     */
    public function validateBorrowLibSystem($account_info, $book_info, $is_admin, $is_order_view)
    {
        //最后判断读者借阅权限
        $controllerObj = new Controller();
        $libApi = $controllerObj->getLibApiObj();

        //馆藏书需要分别判断，因为接口不支持一次性判断多本
        $now_able_borrow_num = 0; //此次非一卡通借阅量
        $now_cloud_able_borrow_num = 0; //此次一卡通
        foreach ($book_info as $key => $val) {
            $res = $libApi->validateBorrow($account_info['account'], $val['barcode']);

            if ($res['code'] != 200) {
                throw new \Exception($res['msg']);
            }

            $barcode_info = $libApi->getAssetByBarcode($val['barcode']);
            //验证当前条形码 的馆藏地，是否允许借阅
            $localList = BookHomePurchaseSet::where('type', 19)->value('content');  //检索的馆藏地
            if ($localList) {
                $localList = explode(',', $localList);
                // if(!in_array($barcode_info['content']['initLocal'],$localList)){
                //     throw new \Exception('条形码：'.$val['barcode'].' “所属馆藏地” 不支持线上借阅');
                // }

                if (!in_array($barcode_info['content']['curLocal'], $localList)) {
                    throw new \Exception('条形码：' . $val['barcode'] . ' “当前所在馆藏地” 不支持线上借阅');
                }
            }
            //验证当前条形码 是一卡通还是非一卡通
            if ($barcode_info['code'] === 200) {
                //ecardflag 为1 则为一卡通。其它情况为非一卡通。没返回就是 非一卡通
                if (isset($barcode_info['content']['ecardFlag']) && $barcode_info['content']['ecardFlag'] == 1) {
                    $now_cloud_able_borrow_num++;
                } else {
                    $now_able_borrow_num++;
                }
            } else {
                throw new \Exception('数据获取失败'); //第一个失败就全部失败
            }
        }

        //自己判断借阅本书是否上限
        $result = $libApi->getReaderInfo($account_info['account']); //获取读者借阅本书
        if ($result['code'] != 200) {
            throw new \Exception($result['msg']);
        }

        // $count = count($book_info);
        /* if ($result['content']['reader']['eCardType']) {
            $num = $result['content']['readerBorrowInfo']['cloudAbleBorrowNum'] - $result['content']['readerBorrowInfo']['cloudCurrentBorrowNum'] - $count;
        } else {
            $num = $result['content']['readerBorrowInfo']['ableBorrowNum'] - $result['content']['readerBorrowInfo']['currentBorrowNum'] - $count;
        }*/

        $now_able_borrow_num = $result['content']['readerBorrowInfo']['ableBorrowNum'] - $now_able_borrow_num;

        // $now_cloud_able_borrow_num = $result['content']['readerBorrowInfo']['cloudAbleBorrowNum'] - $now_cloud_able_borrow_num;
        if (isset($result['content']['readerBorrowInfo']['cloudAbleBorrowNum'])) {
            $now_cloud_able_borrow_num = $result['content']['readerBorrowInfo']['cloudAbleBorrowNum'] - $now_cloud_able_borrow_num;
        } else {
            $now_cloud_able_borrow_num = $now_cloud_able_borrow_num;
        }

        if ($now_able_borrow_num < 0 || $now_cloud_able_borrow_num < 0) {
            throw new \Exception('此次借阅书籍本数过多，超过用户借阅上限，暂不允许借阅');
        }

        //查询用户在借阅流程中的数据本数
        if (!$is_admin && !$is_order_view) {
            $borrowing_data = BookHomeOrder::select('id', 'type')
                ->where('account_id', $account_info['account_id'])
                ->where(function ($query) {
                    $query->Orwhere('is_pay', 1)
                        ->Orwhere('is_pay', 2)
                        ->Orwhere('is_pay', 6);
                })->get();

            $borrowing_able_borrow_num = 0;
            $borrowing_cloud_able_borrow_num = 0;
            $bookHomeOrderBookModelObj = new BookHomeOrderBook();
            $libBookBarcodeModelObj = new LibBookBarcode();
            foreach ($borrowing_data as $key => $val) {
                $book_home_order_book_data = $bookHomeOrderBookModelObj->select('type', 'barcode_id')->where('order_id', $val['id'])->get();

                foreach ($book_home_order_book_data as $k => $v) {
                    //新书为非一卡通
                    if ($v['type'] == 1) {
                        $borrowing_able_borrow_num++;
                    } else {
                        $barcode = $libBookBarcodeModelObj->where('id', $v['barcode_id'])->value('barcode');

                        //验证当前条形码 是一卡通还是非一卡通
                        $barcode_info = $libApi->getAssetByBarcode($barcode);
                        if ($barcode_info['code'] === 200) {
                            //ecardflag 为1 则为一卡通。其它情况为非一卡通。没返回就是 非一卡通
                            if (isset($barcode_info['content']['ecardFlag']) && $barcode_info['content']['ecardFlag'] == 1) {
                                $borrowing_cloud_able_borrow_num++;
                            } else {
                                $borrowing_able_borrow_num++;
                            }
                        } else {
                            throw new \Exception('数据获取失败'); //第一个失败就全部失败
                        }
                    }
                }
            }

            $now_able_borrow_num -= $borrowing_able_borrow_num;
            $now_cloud_able_borrow_num -= $borrowing_cloud_able_borrow_num;

            if ($now_able_borrow_num < 0 || $now_cloud_able_borrow_num < 0) {
                //  throw new \Exception('申请借阅书籍本数过多，超过用户借阅上限，请等待后台管理员审核');
            }
        }
    }
    /**
     *判断此数据是否在采购流程中
     */
    public function checkBookHomePurchaseIng($book_info, $is_admin, $is_order_view)
    {
        //如果是后台  或者 是订单界面就不验证
        if ($is_admin || $is_order_view) {
            return true;
        }
        $obj = new BookHomeOrder();
        foreach ($book_info as $key => $val) {
            $res = $obj->from($obj->getTable() . ' as n')
                ->join('book_home_order_book as b', 'b.order_id', '=', 'n.id')
                ->join('lib_book_barcode as l', 'l.id', '=', 'b.barcode_id')
                ->where('l.barcode', $val['barcode'])->where(function ($query) {
                    $query->Orwhere('n.is_pay', 1)
                        ->Orwhere('n.is_pay', 2)
                        ->Orwhere('n.is_pay', 6);
                })->first();
            if ($res) {
                throw new \Exception('条形码：【' . $val['barcode'] . '】，已有用户提交申请，暂不允许借阅');
            }
        }
    }

    /**
     * 电话号码隐藏中间几位
     * @param tel
     */
    public static function disTel($tel)
    {
        $tel = str_replace('-', '', $tel);
        $substr_tel = substr($tel, 3, -4);
        $tel = substr_replace($tel, str_repeat('*', strlen($substr_tel)), 3, -4);
        return $tel;
    }


    /**
     * 获取用户积分信息，增加用户积分和扣除积分
     */
    public function getBorrowInfo($user_id, $account_id)
    {
        $start_time = "2021-01-01"; //开始计算时间，以前是从2020年开始的
        $start_year = date('Y', strtotime($start_time)); //开始年

        //获取今年借阅数据
        $now_year = date('Y');
        $now_start_time = date('Y') . '-01-01';
        $now_end_time = date('Y-m-d');


        if ($now_year >= $start_year && $start_time < $now_end_time) {
            $now_start_time = $now_year == $start_year ? $start_time : $now_start_time;
            $this->getBorrowScore($user_id, $account_id, $now_year, $now_start_time, $now_end_time);
        }
        //获取去年借阅数据
        $last_year = $now_year - 1;
        $last_start_time = $last_year . '-01-01';
        $last_end_time = $last_year . '-12-31';

        if ($last_year >= $start_year && $start_time < $last_end_time) {
            $last_start_time = $last_year == $start_year ? $start_time : $last_start_time;
            $this->getBorrowScore($user_id, $account_id, $last_year, $last_start_time, $last_end_time);
        }
    }

    /**
     * 根据具体借还数据，增减积分
     */
    public function getBorrowScore($user_id, $account_id, $year, $start_time, $end_time)
    {
        $account_info = UserLibraryInfo::select('account', 'score')->find($account_id);

        $controllerObj = new Controller();
        $libApi = $controllerObj->getLibApiObj();
        $getLastBorrowInfo = $libApi->getReturnData($account_info->account, 1, 1000, $year, $start_time, $end_time, null, true);

        if (!empty($getLastBorrowInfo['code']) && $getLastBorrowInfo['code'] != 200) {
            return false; //代表无数据
        }
        $userBorrowNumberByYear = UserAccountBorrow::select('id', 'number')
            ->where('account_id', $account_id)
            ->where('year', $year)
            ->first();

        /*   $number = !empty($userBorrowNumberByYear['number']) ? $userBorrowNumberByYear['number'] : 0;
      //  dump($year);
      //  dump($number);
      //  dump($getLastBorrowInfo);
        if($getLastBorrowInfo['total'] <= $number){
            return true;//表示已经添加完毕
        }
       // dump(!empty($userBorrowNumberByYear));
        if(!empty($userBorrowNumberByYear)){
            $getLastBorrowInfo['list'] = array_splice($getLastBorrowInfo['list'], $number);//获取新增的项目
        } */
        //   dump($getLastBorrowInfo);die;
        DB::beginTransaction();
        try {
            // dump($getLastBorrowInfo['list']);
            $userAccountBorrowLogModelObj = new UserAccountBorrowLog();

            //已经计算过的id
            $use_api_id = $userAccountBorrowLogModelObj->where('cardno', $account_info->account)->pluck('api_id');
            foreach ($getLastBorrowInfo['list'] as $key => $val) {
                //判断此记录是否已经使用
                if (in_array($val['id'], $use_api_id)) {
                    continue;
                }

                $score_info = $this->getScoreInfo($val['eventType']);
                $scoreRuleObj = new ScoreRuleController();
                $score_status = $scoreRuleObj->checkScoreStatus($score_info['type'], $user_id, $account_id);
                if ($score_status['code'] == 202 || $score_status['code'] == 203) {
                    throw new Exception($score_status['msg']);
                }

                if ($score_status['code'] == 200) {
                    //判断是否是归还
                    if ($val['eventType'] == 'Eg') {
                        //获取借阅时间
                        $borrow_times = explode("借出日期：", $val['notes']);
                        $borrow_time = isset($borrow_times[1]) ? explode("，", $borrow_times[1])[0] : '';

                        if (date('Y-m-d', strtotime($borrow_time)) == date('Y-m-d', strtotime($val['updateDateTime']))) {

                            //数据添加到数据表
                            $val['api_id'] = $val['id'];
                            $val['create_time'] = date('Y-m-d H:i:s');
                            unset($val['id'], $val['ip']);
                            $userAccountBorrowLogModelObj->insert($val);
                            continue;
                        }
                    }

                    //用户积分操作  与 系统消息
                    if (!empty($val['updateDateTime'])) {
                        $change_time = $val['updateDateTime'];
                    } else {
                        $borrow_time = explode("借出日期：", $val['notes']);
                        $change_time = isset($borrow_time[1]) ? explode("，", $borrow_time[1])[0] : '';
                    }

                    $controllerObj = new Controller();
                    $system_id = $controllerObj->systemAdd($score_status['score_info']['type_name'], $user_id, 50, 0, $score_status['score_info']['intro'] . " ，书名为：《" . $val['title'] . '》', $change_time);

                    $scoreRuleObj->scoreChange($score_status, $user_id, $account_id, $system_id); //添加积分消息
                }

                //数据添加到数据表
                $val['api_id'] = $val['id'];
                $val['create_time'] = date('Y-m-d H:i:s');
                unset($val['id'], $val['ip']);
                $userAccountBorrowLogModelObj->insert($val);


                /*//只返回已归还的记录
                if($val['eventType'] === 'Eg' || $val['eventType'] === 'Ec' || $val['eventType'] === 'Ed' || $val['eventType'] === 'Ef') {
                      ["id"] => int(5489913)
                      ["eventType"] => string(2) "Eg"
                      ["loginWay"] => string(8) "DLibsApi"
                      ["readerId"] => int(553044)
                      ["assetId"] => int(900755)
                      ["servrequestId"] => int(0)
                      ["metatable"] => string(9) "i_biblios"
                      ["metaid"] => int(685689)
                      ["curSublib"] => string(2) "BN"
                      ["curLocal"] => string(4) "BN_C"
                      ["initSublib"] => string(2) "BN"
                      ["initLocal"] => string(4) "BN_C"
                      ["cardno"] => string(14) "01131000999999"
                      ["readerLib"] => string(2) "BN"
                      ["realName"] => string(12) "测试读者"
                      ["barcode"] => string(14) "01079600000007"
                      ["cirType"] => string(3) "001"
                      ["volumeno"] => int(0)
                      ["title"] => string(21) "催眠师手记 . Ⅱ"
                      ["author"] => string(9) "高铭著"
                      ["isbn"] => string(17) "978-7-5502-9421-9"
                      ["publish"] => string(38) "北京:北京联合出版公司 , 2018"
                      ["callno"] => string(12) "R395.2/3/(2)"
                      ["price"] => string(8) "CNY48.00"
                      ["ip"] => string(9) "127.0.0.1"
                      ["notes"] => string(191) "还回！条码号：【01079600000007】，题名：催眠师手记 . Ⅱ，借出日期：2020-12-23 00:00:00，应还日期：2021-01-22 00:00:00，实际还回日期：2020-12-25 00:00:00"
                      ["adminName"] => string(12) "btkj_bxdd_yz"
                      ["updateDateTime"] => string(19) "2020-12-25 09:41:14"
                      ["eventTypeNote"] => string(18) "读者还回文献"
                      ["loginWayNote"] => string(20) "DLibsApi调用方式"
                      ["curSublibNote"] => string(24) "重庆市巴南图书馆"
                      ["curLocalNote"] => string(18) "总馆成人图书"
                      ["initSublibNote"] => string(24) "重庆市巴南图书馆"
                      ["initLocalNote"] => string(18) "总馆成人图书"
                      ["readerLibNote"] => string(24) "重庆市巴南图书馆"
                      ["cirTypeNote"] => string(18) "一卡通中文书"
                }*/
            }

            //修改次数
            if (empty($userBorrowNumberByYear)) {
                UserAccountBorrow::create([
                    'account_id' => $account_id,
                    'year' => $year,
                    'number' => $getLastBorrowInfo['total'],
                    'create_time' => date('Y-m-d H:i:s'),
                    'change_time' => date('Y-m-d H:i:s'),
                ]);
            } else {
                $userBorrowNumberByYear->number = $getLastBorrowInfo['total'];
                $userBorrowNumberByYear->change_time = date('Y-m-d H:i:s');
                $userBorrowNumberByYear->save();
            }

            DB::commit();
            return true;
        } catch (\Exception $e) {
            //  echo $e->getMessage();
            Log::error($e->getMessage());
            DB::rollBack();
            return false;
        }
    }
    //BORROW("Ea", "读者借出"),
    /** 读者还回文献Eg */
    //  RETURN("Eg", "读者还回文献"),    //下面的枚举值，不能管什么情况，都会产生一条这个数据
    /** 读者续借Eb */
    // RENEW("Eb", "读者续借"),
    /** 读者过期Ec */
    //  OVERDUE("Ec", "读者过期"),
    /** 文献损坏Ed */
    //  DAMAGE("Ed", "文献损坏"),
    /** 读者丢失文献Ef */
    //  LOST("Ef", "读者丢失文献"),

    /**
     * 获取对应积分
     */
    public function getScoreInfo($eventType)
    {
        switch ($eventType) {
            case 'Ea':
                $type = 8;
                break;
            case 'Eg':
                $type = 9;
                break;
            case 'Ec':
                $type = 10;
                break;
            case 'Ed':
                $type = 11;
                break;
            case 'Ef':
                $type = 12;
                break;
            default:
                return false;
        }
        $score = ScoreInfo::where('type', $type)->first();
        return $score;
    }

    /**
     * 根据订单id获取书籍列表
     * @param book_id  多个数组形式
     */
    public function getBookInfoList($order_id, $field = [])
    {
        if (empty($field)) {
            $field = ['o.id', 'book_name', 'author', 'press', 'pre_time', 'isbn', 'b.img', 'b.price', 'b.book_num', 'l.barcode', 'l.cur_local_note'];
        }
        $book_info = $this->from('book_home_order_book as o')
            ->select($field)
            ->join('lib_book as b', 'o.book_id', '=', 'b.id')
            ->join('lib_book_barcode as l', 'o.barcode_id', '=', 'l.id')
            ->where('o.order_id', $order_id)
            ->get()
            ->toArray();
        return $book_info;
    }
}
